package jehc.cloud.common.session;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jehc.cloud.common.cache.redis.RedisUtil;
import jehc.cloud.common.constant.SessionConstant;
import jehc.cloud.common.idgeneration.UUID;
import jehc.cloud.common.util.ExceptionUtil;
import jehc.cloud.common.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;

/**
 * @Desc SESSION工具
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
public class HttpSessionUtils {	
	Logger logger = LoggerFactory.getLogger(this.getClass());	
	@Value("300")
	protected Integer exp; //  过期时间 ： 秒(默认5分钟)
	@Autowired
	protected RedisUtil redisUtil;

	/**
	 * 获取所有key
	 * @return
	 */
	public List<String> getAllTokenKey(){
		try {
			List tokenList = new ArrayList();
			Set<String> list = redisUtil.getKeys("*");
			for (String token : list ){
				if(token.contains(SessionConstant.TOKEN)){
					tokenList.add(token);
				}
			}
			return tokenList;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类getAllTokenKey方法,Redis Session 读取出现异常",e);
			throw new ExceptionUtil("getAttribute类getAllTokenKey方法，获取Redis出现异常",e.getCause());
		}
	}


	/**
	 * 存放对象到session中并设置有效时间（缺省则为5分钟）
	 * @param key
	 * @param value
	 * @param times
	 */
	public boolean setAttributeExpTime(String key,String value,Integer times) {
		try {
			redisUtil.set(key,value,exp*times);
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setAttributeExpTime方法,设置Redis Session 出现异常",e);
			return false;
		}
	}

	/**
	 * 根据key设置有效时间（缺省则为5分钟）
	 * @param key
	 * @param times
	 */
	public boolean setAttributeExpTime(String key,Integer times) {
		try {
			redisUtil.expire(key,exp*times);
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setAttributeExpTime方法,设置Redis Session 出现异常",e);
			return false;
		}
	}



	/**
	 * 存放信息中（默认不过期）
	 * @param hashName
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean setHashAttribute(String hashName,String key,String value) {
		try {

			logger.info("jedis存放信息：key为{}/value为{}", key, value);
			redisUtil.hset(hashName,key,value);
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setAttribute方法,设置Redis Value 出现异常",e);
			return false;
		}
	}

	/**
	 * 移除 支持批量删除
	 * @param hashName
	 * @param key
	 * @return
	 */
	public boolean delHashKV(String hashName,String key) {
		try {
			if(StringUtils.isEmpty(key)){
				throw new ExceptionUtil("HttpSessionUtils类del方法，未能获取到key");
			}
			redisUtil.hdel(hashName,key);
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类del方法，删除Redis KEY出现异常",e);
			return false;
		}
	}

	/**
	 * 存放信息中（默认5分钟）
	 * @param key
	 * @param value
	 */
	public boolean setAttribute(String key,String value,Integer times) {
		try {
			String codeKey =  key;
			logger.info("jedis存放信息：key为{}/value为{}", codeKey, value);

			if(null == times){
				times = 1;
			}
			redisUtil.set(key,value,exp*times);
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setAttribute方法,设置Redis Value 出现异常",e);
			return false;
		}
		return true;
	}

	/**
	 * 存放信息中并设置时间（默认5分钟）
	 * 注意：时间有效期只针对于顶级Key有效
	 * @param hashName
	 * @param key
	 * @param value
	 * @param times
	 * @return
	 */
	public boolean setHashAttribute(String hashName,String key,String value,Integer times) {
		try {
			String codeKey =  key;
			logger.info("jedis存放信息：hashName为{}/key为{}/value为{}", hashName,codeKey, value);
			if(null == times){
				times = 1;
			}
			redisUtil.hset(hashName,codeKey, value,exp*times);
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setAttribute方法,设置Redis Value 出现异常",e);
			return false;
		}
		return true;
	}
	
	/**
	 * 移除 支持批量删除
	 * @param key
	 */
	public boolean del(String key) {
		try {
			if(StringUtils.isEmpty(key)){
				throw new ExceptionUtil("HttpSessionUtils类del方法，未能获取到key");
			}
			redisUtil.del(key);
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类del方法，删除Redis KEY出现异常",e);
			return false;
		}
	}

	/**
	 * 存放对象到session中（默认不过期）
	 * @param key
	 * @param value
	 */
	public void setAttribute(String key,String value) {
		try {
			logger.info("HttpSessionUtils类setAttribute方法,jedis存放信息：key为{}/value为{}", key, value);
			redisUtil.set(key, value);
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setAttribute方法,设置Redis Session 出现异常",e);
			throw new ExceptionUtil("getAttribute类setAttribute方法，设置Redis值出现异常",e.getCause());
		}
	}

	/**
	 * 根据key获取对象信息
	 * @param key
	 * @return
	 */
	public String getAttribute(String key) {
		try {
			String result = redisUtil.get(key);
			return result;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类getAttribute方法,Redis Session 读取出现异常",e);
			throw new ExceptionUtil("getAttribute类getAttribute方法，获取Redis出现异常",e.getCause());
		}
	}

	/**
	 * 根据HashName,sessionKey获取对象信息
	 * @param hashName
	 * @param key
	 * @return
	 */
	public String getHashAttribute(String hashName, String key) {
		try {
			if(StringUtil.isEmpty(hashName)){
				logger.error("getHashAttribute,未能获取到hashName值");
				throw new ExceptionUtil("getHashAttribute,未能获取到hashName值");
			}
			if(StringUtil.isEmpty(key)){
				logger.error("getHashAttribute,未能获取到sessionKey值");
				throw new ExceptionUtil("getHashAttribute,未能获取到sessionKey值");
			}

			String result = ""+redisUtil.hget(hashName,key);
			return result;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类getHashAttribute方法,Redis Session 读取出现异常",e);
			throw new ExceptionUtil("getAttribute类getHashAttribute方法，获取Redis出现异常",e.getCause());
		}
	}

	/**
	 * 根据sessionKey获取对象信息
	 * @param request
	 * @return
	 */
	public String getVerifyAttribute(HttpServletRequest request) {
		try {
			String result = redisUtil.get(SessionConstant.VERIFY_STORE_PATH+getSessionId(request));
			return result;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类getAttribute方法,Redis Session 读取出现异常",e);
			throw new ExceptionUtil("getAttribute类getAttribute方法，获取Redis出现异常",e.getCause());
		}
	}

	/**
	 * 根据HashName,sessionKey销毁对象
	 * @param hashName
	 * @param sessionKey
	 * @return
	 */
	public Boolean invalidateHash(String hashName, String sessionKey) {
		try {
			String key = sessionKey;
			String result = ""+ redisUtil.hget(hashName,key);
			if(!StringUtils.isEmpty(result)){
				redisUtil.hdel(hashName,key);
			}
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类invalidateHash方法,Redis Session 销毁Session出现异常",e);
			return false;
		}
	}

	/**
	 * 根据sessionKey销毁对象
	 * @param sessionKey
	 * @return
	 */
	public Boolean invalidate(String sessionKey) {
		try {
			String result = redisUtil.get(sessionKey);
			if(!StringUtils.isEmpty(result)){
				redisUtil.del(sessionKey);
			}
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类invalidate方法,Redis Session 销毁Session出现异常",e);
			return false;
		}
	}

//	/**
//	 * 读取并创建sessionId
//	 * @param request
//	 * @return
//	 */
//	public String getSessionId(HttpServletRequest request) {
//		String sessionId = request.getHeader(SessionConstant.SESSIONID);
//		if(StringUtil.isEmpty(sessionId)){
//			return UUID.toUUID();
//		}
//		return sessionId;
//	}

	/**
	 * 读取并创建sessionId
	 * @param request
	 * @return
	 */
	public String getSessionId(HttpServletRequest request) {
		HttpHeaders headers = new HttpHeaders();
		Enumeration<String> headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String key = (String) headerNames.nextElement();
			String value = request.getHeader(key);
			headers.add(key, value);
		}
		String sessionId = request.getHeader(SessionConstant.SESSIONID);
		if(StringUtil.isEmpty(sessionId)){
			return UUID.toUUID();
		}
		return sessionId;
	}
	
		
	/**
	 * 设置Cookie
	 * @param key
	 * @param value
	 * @param response
	 * @return
	 */
	public boolean setCookie(String key,String value, HttpServletResponse response){
		try {
			response.setContentType("text/html;charset=UTF-8");
			response.setCharacterEncoding("UTF-8");
			Cookie cookie = new Cookie(key, value);
			cookie.setPath("/");
//			cookie.setMaxAge(0);//不记录cookie
//			cookie.setMaxAge(-1);//会话级cookie，关闭浏览器失效（session-JSESSIONID就是这种会话级）
//			cookie.setMaxAge(60*60);//过期时间为1小时
			//HttpOnly cookie用于防止跨站点脚本（XSS）攻击，无法通过JavaScript的Document.cookie API访问。 当为cookie设置HttpOnly标志时，它告诉浏览器该服务器应该只访问该特定cookie
			cookie.setHttpOnly(true);
			cookie.setMaxAge(60*60*24);//过期时间为1Day
			response.addCookie(cookie);
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setCookie方法,设置Cookie出现异常",e);
			return false;
		}
	}
	
	/**
	 * 设置setHeader
	 * @param key
	 * @param value
	 * @param response
	 * @return
	 */
	public boolean setHeader(String key,String value, HttpServletResponse response){
		try {
			response.addHeader(key, value);
			return true;
		} catch (Exception e) {
			logger.error("HttpSessionUtils类setHeader方法,设置Header出现异常",e);
			return false;
		}
	}
}

